//============================================================================================
/**
 * @file	pkthln_svdata.c
 * @brief	ポケスロンのセーブ関連
 * @author	Nozomu Saito
 * @date	2008.08.18
 *
 * モジュール名：PkthlnSv_
 */
//============================================================================================

#include "savedata/pkthln_svdata.h"
#include "savedata/savedata.h"

#include "gflib/assert.h"

typedef struct PKTHLN_SV_DATA_tag
{
	//コースデータ
	PKTH_COURSE CourseData[ALONE_COURSE_NUM];			//44x5 = 220

	//メダルデータ
	u8 Medal[493];
	u8 medal_dummy[3];	//４バイトアライメント用ダミー	//496

	//競技データ
	PKTH_EVT_DATA EvtData[PKTHLN_EVT_MAX];			//44x10 = 440
	PKTH_COMM_EVT_DATA CommEvtData[PKTHLN_EVT_MAX];	//164x10 = 1640
	//ベスト1のレコードのスコア（非通信時）
	u16 BestRecScore[PKTHLN_EVT_MAX];				//2x10 = 20

	//ランキングデータ
	PKTH_RNK_DATA RnkData;			//116

	//ポケスロン買い物ポイント
	int ThlnPoint;					//4

	// ポケスロンランキングデータ公開フラグ（計 27 bit)
	u32 RankingAppear;				// 4

	// ポケスロンショップフラグ（１日１回しか買えない。０時を越えるとクリア）
	u16 ShopFlag;					// 2

	// パディング（セーブデータを４バイトに合わせるため）
	u16 etc;						// 2

}PKTHLN_SV_DATA;		//計2944byte

typedef struct PKTH_WPOKE_SV_DATA_tag
{
	PKTH_WIN_POKE Poke[3];		//4x3=12byte
	u8 dumy[28];				//セーブデータをずらさないためのダミーデータ28byte
}PKTH_WPOKE_SV_DATA;

// 構造体が想定のサイズとなっているかチェック
#ifdef PM_DEBUG
#ifdef _NITRO
SDK_COMPILER_ASSERT(sizeof(PKTHLN_SV_DATA) == 2944);
SDK_COMPILER_ASSERT(sizeof(PKTH_WPOKE_SV_DATA) == 40);

#endif
#endif

//----------------------------------------------------------
/**
 * @brief	セーブワークサイズ取得
 * @param	none
 *
 * @return	int		サイズ
 */
//----------------------------------------------------------
int PkthlnSv_GetWorkSize(void)
{
	return sizeof(PKTHLN_SV_DATA);
}

//----------------------------------------------------------
/**
 * @brief	セーブワーク初期化
 * @param	sv			セーブワーク
 *
 * @return	none
 */
//----------------------------------------------------------
void PkthlnSv_Init(void *sv)
{
	u8 i,j;
	PKTHLN_SV_DATA *wk = (PKTHLN_SV_DATA*)sv;

	MI_CpuClear8(wk,sizeof(PKTHLN_SV_DATA));

	OS_Printf("%d\n",sizeof(PKTH_COURSE));
	OS_Printf("%d\n",sizeof(PKTH_EVT_DATA));
	OS_Printf("%d\n",sizeof(PKTH_COMM_EVT_DATA));
	OS_Printf("%d\n",sizeof(PKTH_RNK_DATA));

	OS_Printf("PkthlnSaveSize = %d\n",sizeof(PKTHLN_SV_DATA));
	//レコードを0xffffで埋める
	for (i=0;i<PKTHLN_EVT_MAX;i++){
		for (j=0;j<BEST_FIVE;j++){
			wk->EvtData[i].RcMs[j].Record = REC_NO_DATA;
			wk->CommEvtData[i].EvtData.RcMs[j].Record = REC_NO_DATA;
		}
	}
}

//---------------------------------------------------------------------------
/**
 * @brief	セーブデータポインタ取得
 * @param	sv			セーブデータ保持ワークへのポインタ
 *
 * @return	セーブデータポインタ
 */
//---------------------------------------------------------------------------
PKTHLN_SV_DATA_PTR PkthlnSv_GetSaveData(SAVEDATA * sv)
{
	PKTHLN_SV_DATA * data;
	data = SaveData_Get(sv, GMDATA_ID_POKETHLON_SAVE);
	return data;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用コースデータ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
const PKTH_COURSE *PkthlnSv_GetCrsDataAloneCnst(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->CourseData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロンメダルデータ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
const u8 *PkthlnSv_GetMedalDataCnst(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->Medal;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技データ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
const PKTH_EVT_DATA *PkthlnSv_GetEvtDataAloneCnst(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->EvtData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技データ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
const PKTH_COMM_EVT_DATA *PkthlnSv_GetEvtDataCommCnst(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->CommEvtData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技ベストレコードのスコア配列取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
u16 *PkthlnSv_GetBestRecScore(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->BestRecScore;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技データ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
const PKTH_RNK_DATA *PkthlnSv_GetRnkDataCnst(PKTHLN_SV_DATA_PTR ptr)
{
	return &ptr->RnkData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用コースデータ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
PKTH_COURSE *PkthlnSv_GetCrsDataAlone(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->CourseData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロンメダルデータ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
u8 *PkthlnSv_GetMedalData(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->Medal;
}

//---------------------------------------------------------------------------
/**
 * @brief	指定コースメダルを持っているかを返す
 * @param	ptr			セーブデータポインタ
 * @param	inCrsID		コースＩＤ
 * @param	inMonsNo	モンスターナンバー
 *
 * @return	BOOL		TRUE:持っている		FALSE:持っていない
 */
//---------------------------------------------------------------------------
BOOL PkthlnSv_IsMedal(PKTHLN_SV_DATA_PTR ptr, const CRS_ID inCrsID, const int inMonsNo)
{
	int idx;
	int flg;

#ifdef PM_DEBUG
	if ( inCrsID == CRS_ID_MAS ){
		return FALSE;
	}
#endif
	if ( (inCrsID<0) || (CRS_ID_JMP<inCrsID) ){
		GF_ASSERT(0);
		return FALSE;
	}

	idx = inMonsNo - 1;

	if ( idx < 0){
		GF_ASSERT(0);
		return FALSE;
	}

	flg = (ptr->Medal[idx] >> inCrsID) & 0x1;
	if (flg){
		return TRUE;
	}

	return FALSE;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技データ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
PKTH_EVT_DATA *PkthlnSv_GetEvtDataAlone(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->EvtData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技データ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
PKTH_COMM_EVT_DATA *PkthlnSv_GetEvtDataComm(PKTHLN_SV_DATA_PTR ptr)
{
	return ptr->CommEvtData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技データ先頭アドレス取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
PKTH_RNK_DATA *PkthlnSv_GetRnkData(PKTHLN_SV_DATA_PTR ptr)
{
	return &ptr->RnkData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用コースデータデータセット関数
 *
 * @param	ptr			セーブデータポインタ
 * @param	inCrsID		コースID		pkthln_svdata.h	参照
 * @param	inCrsData	コースデータ
 *
 * @return	none
 */
//---------------------------------------------------------------------------
void PkthlnSv_SetCrsDataAlone(	PKTHLN_SV_DATA_PTR ptr, const CRS_ID inCrsID,
								const PKTH_COURSE *inCrsData	)
{
#ifdef PM_DEBUG
	if ( inCrsID == CRS_ID_MAS ){
		return;
	}
#endif
	if ( (inCrsID<0) || (CRS_ID_JMP<inCrsID) ){
		GF_ASSERT(0);
		return;
	}

	ptr->CourseData[inCrsID] = *inCrsData;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロンメダルデータセット関数
 * @param	ptr			セーブデータポインタ
 * @param	inCrsID		コースＩＤ
 * @param	inMonsNo
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
void PkthlnSv_SetMedalData(PKTHLN_SV_DATA_PTR ptr, const CRS_ID inCrsID, const int inMonsNo)
{
	int idx;
	u8 flg;
#ifdef PM_DEBUG
	if ( inCrsID == CRS_ID_MAS ){
		return;
	}
#endif
	if ( (inCrsID<0) || (CRS_ID_JMP<inCrsID) ){
		GF_ASSERT(0);
		return;
	}

	idx = inMonsNo - 1;

	if ( idx < 0){
		GF_ASSERT(0);
		return;
	}

	flg = 1 << inCrsID;
	ptr->Medal[idx] |= flg;
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロンメダルデータセット関数
 * @param	ptr			セーブデータポインタ
 * @param	inMask		コースマスク		pthln_svdata.h	define参照
 * @param	inMonsNo
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
void PkthlnSv_SetMedalDataByBit(PKTHLN_SV_DATA_PTR ptr, const u8 inMask, const int inMonsNo)
{
	u8 i;
	int idx;
	u8 flg;
	idx = inMonsNo - 1;

	if ( idx < 0){
		GF_ASSERT(0);
		return;
	}
	for(i=0;i<MEDAL_TYPE_MAX;i++){
		u8 bit;
		bit = (inMask >> i) & 0x1;
		if (bit){
			flg = 1 << i;
			ptr->Medal[idx] |= flg;
		}
	}
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロンメダルデータ取得関数
 * @param	ptr			セーブデータポインタ
 * @param	inMonsNo	モンスターナンバー
 *
 * @return	データ先頭アドレス
 */
//---------------------------------------------------------------------------
const u8 PkthlnSv_GetPokeMedalData(PKTHLN_SV_DATA_PTR ptr, const int inMonsNo)
{
	u8 i;
	int idx;
	u8 flg;
	idx = inMonsNo - 1;

	if ( idx < 0){
		GF_ASSERT(0);
		return 0;
	}

	return ptr->Medal[idx];
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン一人用競技データセット関数
 * @param	ptr			セーブデータポインタ
 * @param	inEvtID		競技ＩＤ
 * @param	inEvtData	競技データ
 *
 * @return	none
 */
//---------------------------------------------------------------------------
void PkthlnSv_SetEvtDataAlone(PKTHLN_SV_DATA_PTR ptr, const int inEvtID, const PKTH_EVT_DATA *inEvtData )
{
	if ( (inEvtID < 0)||(inEvtID >= PKTHLN_EVT_MAX) ){
		GF_ASSERT(0);
		return;
	}
	ptr->EvtData[inEvtID] = (*inEvtData);
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン通信用競技データセット関数
 * @param	ptr			セーブデータポインタ
 * @param	inEvtID		競技ＩＤ
 * @param	inEvtData	競技データ
 *
 * @return	none
 */
//---------------------------------------------------------------------------
void PkthlnSv_SetEvtDataComm(PKTHLN_SV_DATA_PTR ptr, const int inEvtID, const PKTH_COMM_EVT_DATA *inEvtData )
{
	if ( (inEvtID < 0)||(inEvtID >= PKTHLN_EVT_MAX) ){
		GF_ASSERT(0);
		return;
	}
	ptr->CommEvtData[inEvtID] = (*inEvtData);
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン買い物ポイント加算関数
 * @param	ptr			セーブデータポインタ
 * @param	inVal		加算値
 *
 * @return	none
 */
//---------------------------------------------------------------------------
void PkthlnSv_AddThlnPoint (PKTHLN_SV_DATA_PTR ptr, const u16 inVal )
{
	ptr->ThlnPoint += inVal;
	if ( ptr->ThlnPoint > THLN_POINT_MAX ){
		ptr->ThlnPoint = THLN_POINT_MAX;
	}
}

//---------------------------------------------------------------------------
/**
 * @brief	ポケスロン買い物ポイント減算関数
 * @param	ptr			セーブデータポインタ
 * @param	inVal		減算値
 *
 * @return	none
 */
//---------------------------------------------------------------------------
void PkthlnSv_SubThlnPoint (PKTHLN_SV_DATA_PTR ptr, const u16 inVal )
{
	ptr->ThlnPoint -= inVal;
	if ( ptr->ThlnPoint < 0 ){
		ptr->ThlnPoint = 0;
	}
}

//---------------------------------------------------------------------------
/**
 * @brief	現在ポケスロン買い物ポイント取得
 * @param	ptr			セーブデータポインタ
 *
 * @return	val			買い物ポイント
 */
//---------------------------------------------------------------------------
u32 PkthlnSv_GetThlnPoint ( PKTHLN_SV_DATA_PTR ptr )
{
	return ptr->ThlnPoint;
}

//==============================================================================
/**
 * @brief   ポケスロンランキング公開情報フラグの取得
 *
 * @param   ptr		PKTHLN_SV_DATA_PTR
 * @param   index	0 - PKTHLN_DATA_CARD_MAX( = 27まで )
 *
 * @retval  u16 PkthlnSv_GetRankingAppear
 */
//==============================================================================
int PkthlnSv_GetRankingAppear ( PKTHLN_SV_DATA_PTR ptr, int index )
{
	GF_ASSERT( index < PKTHLN_DATA_CARD_MAX );

	// 指定のランキング公開フラグはビットが立っているか取得
	return (ptr->RankingAppear>>index)&1;
}

//==============================================================================
/**
 * @brief   ランキング公開フラグを立てる
 *
 * @param   ptr		PKTHLN_SV_DATA_PTR
 * @param   index	0 - PKTHLN_DATA_CARD_MAX( = 27まで )
 *
 * @retval  void PkthlnSv_SetRankingAppear
 */
//==============================================================================
void PkthlnSv_SetRankingAppear ( PKTHLN_SV_DATA_PTR ptr, int index )
{
	GF_ASSERT( index < PKTHLN_DATA_CARD_MAX );

	// 指定のビットを立てる
	ptr->RankingAppear |= 1<<index;
}

//==============================================================================
/**
 * @brief   ランキング公開フラグをリセットする
 *
 * @param   ptr		PKTHLN_SV_DATA_PTR
 * @param   index	0 - PKTHLN_DATA_CARD_MAX( = 27まで )
 *
 * @retval  void PkthlnSv_SetRankingAppear
 */
//==============================================================================
void PkthlnSv_ResetRankingAppear ( PKTHLN_SV_DATA_PTR ptr, int index )
{
	GF_ASSERT( index < PKTHLN_DATA_CARD_MAX );

	// 指定のビットを下ろす
	ptr->RankingAppear ^= 1<<index;
}

//==============================================================================
/**
 * @brief   ポケスロンショップの今日のアイテムが買われているかどうか取得
 *
 * @param   ptr		PKTHLN_SV_DATA_PTR
 * @param   index	0 - 12 (日によってアイテムは変わるので番号のみ指定）
 *
 * @retval  u16 PkthlnSv_GetShopFlag
 */
//==============================================================================
int PkthlnSv_GetShopFlag ( PKTHLN_SV_DATA_PTR ptr, int index )
{
	// 指定のショップアイテム情報はビットが立っているか取得
	return (ptr->ShopFlag>>index)&1;
}

//==============================================================================
/**
 * @brief   ショップ購入情報のセット（１日で消える）
 *
 * @param   ptr			PKTHLN_SV_DATA_PTR
 * @param   index		0 - 12 (日によってアイテムは変わるので番号のみ指定）
 *
 * @retval  none
 */
//==============================================================================
void PkthlnSv_SetShopFlag ( PKTHLN_SV_DATA_PTR ptr, int index )
{
	// 指定のビットを立てる
	ptr->ShopFlag |= 1<<index;

}

//==============================================================================
/**
 * @brief   ポケスロンショップ購入情報のクリア
 *
 * @param   ptr		PKTHLN_SV_DATA_PTR
 *
 * @retval  none
 */
//==============================================================================
void PkthlnSv_ClearShopFlag ( PKTHLN_SV_DATA_PTR ptr )
{
	ptr->ShopFlag = 0;
}


//優勝自分ポケモン関連

//----------------------------------------------------------
/**
 * @brief	セーブワークサイズ取得
 * @param	none
 *
 * @return	int		サイズ
 */
//----------------------------------------------------------
int PkthlnWPokeSv_GetWorkSize(void)
{
	return sizeof(PKTH_WPOKE_SV_DATA);
}

//----------------------------------------------------------
/**
 * @brief	セーブワーク初期化
 * @param	sv			セーブワーク
 *
 * @return	none
 */
//----------------------------------------------------------
void PkthlnWPokeSv_Init(void *sv)
{
	u8 i,j;
	PKTH_WPOKE_SV_DATA *wk = (PKTH_WPOKE_SV_DATA*)sv;
	MI_CpuClear8(wk,sizeof(PKTH_WPOKE_SV_DATA));
}

//---------------------------------------------------------------------------
/**
 * @brief	優勝ポケデータの先頭アドレス取得
 * @param	sv			セーブデータ保持ワークへのポインタ
 *
 * @return	データポインタ
 */
//---------------------------------------------------------------------------
PKTH_WIN_POKE* PkthlnWPokeSv_GetSaveData(SAVEDATA * sv)
{
	PKTH_WPOKE_SV_DATA * data;
	data = SaveData_Get(sv, GMDATA_ID_PKTH_WPOKE_SAVE);

	return data->Poke;
}
